package com.warrior.superdata.util;

import com.alibaba.fastjson.JSONObject;
import com.warrior.superdata.constants.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.util.StringUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
public class CommonUtil {

    private final static char UNDERLINE = '_';

    private static final String FORMAT_TIME_SHORT = "yyyy-MM-dd";

    private static final String DATE_TIME_FOMART = "yyyy-MM-dd HH:mm:ss";

    /**
     * 校验关键字是否为18位身份证号
     *
     * @param q
     * @return
     */
    public static Boolean matchQ(String q) {
        String regex = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        return q.matches(regex);
    }

    /**
     * 将驼峰转为下横线
     * 比如createBy  ---> create_by
     *
     * @param param
     * @return
     */
    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }


    /**
     * 第一个为大写
     *
     * @param param
     * @return
     */
    public static String camelToUnderlineU(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString().substring(1);
    }


    public static TimeUnit getTimeUtil(String type) {
        if (StringUtils.isEmpty(type)) {
            return TimeUnit.SECONDS;
        }
        TimeUnit result = null;
        switch (type) {
            case "S":
                result = TimeUnit.SECONDS;
                break;
            case "M":
                result = TimeUnit.MINUTES;
                break;
            case "H":
                result = TimeUnit.HOURS;
                break;
            case "D":
                result = TimeUnit.DAYS;
                break;
            default:
                result = TimeUnit.SECONDS;
        }
        return result;
    }

    /**
     * 创建UUID
     *
     * @param withBreak
     * @return
     */
    public static String createUUID(boolean withBreak) {
        String result = UUID.randomUUID().toString();
        if (!withBreak) {
            result = result.replace("-", "");
        }
        return result;
    }


    /**
     * 时间调整  比如  输入 2020-05-01  5   结果是 2020-05-06
     *
     * @param dataStr
     * @param date
     * @return
     */
    public static String addDay(String dataStr, int date) {
        if (StringUtils.isEmpty(dataStr)) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_TIME_SHORT);
        try {
            Date dt = sdf.parse(dataStr);
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(dt);
            rightNow.add(Calendar.DATE, date);
            Date dt1 = rightNow.getTime();
            return sdf.format(dt1);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * LocalDateTime 转 字符串
     *
     * @param localDateTime
     * @param formatString
     * @return
     */
    public static String localDateTimeToString(LocalDateTime localDateTime, String formatString) {
        if (localDateTime == null) {
            return null;
        }
        formatString = Strings.isBlank(formatString) ? DATE_TIME_FOMART : formatString;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatString);
        return dateTimeFormatter.format(localDateTime);
    }

    public static String localDateTimeToString(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        String formatString = DATE_TIME_FOMART;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatString);
        return dateTimeFormatter.format(localDateTime);
    }


    public static String getYear(LocalDateTime localDateTime) {
        if (Objects.nonNull(localDateTime)) {
            return String.valueOf(localDateTime.getYear());
        }
        return String.valueOf(LocalDateTime.now().getYear());
    }

    public static String getYear(String strTime) {
        if (StringUtils.isEmpty(strTime)) {
            return null;
        }
        return strTime.substring(0, 4);
    }

    public static String getCurrentTimeStr() {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_FOMART);
        return dateTimeFormatter.format(LocalDateTime.now());
    }

    public static String getCurrentShortTimeStr() {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(FORMAT_TIME_SHORT);
        return dateTimeFormatter.format(LocalDateTime.now());
    }

    /**
     * String 转 LocalDatetime
     *
     * @param timeStr
     * @param formatString
     * @return
     */
    public static LocalDateTime stringToLocalDateTime(String timeStr, String formatString) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(Strings.isBlank(formatString) ? DATE_TIME_FOMART : formatString);
        LocalDateTime result = LocalDateTime.parse(timeStr, dateTimeFormatter);
        return result;
    }

    /**
     * localDateTime 转 时间戳
     *
     * @param localDateTime
     * @return
     */
    public static long localDateTimeToTimestamp(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    public static String long2Str(Long timeStamp) {
        SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FOMART); //设置格式
        return format.format(timeStamp);
    }

    public static String long2Str(Date timeStamp) {
        SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FOMART); //设置格式
        return format.format(timeStamp);
    }


    public static String contactObjs(Object... args) {
        StringBuilder sb = new StringBuilder();
        for (Object obj : args) {
            if (obj == null || StringUtils.isEmpty(obj.toString())) {
                sb.append(":");
            } else {
                sb.append(obj.toString()).append(":");
            }
        }
        String str = sb.toString();
        return str.length() > 0 ? str.substring(0, str.length() - 1) : str;
    }

    public static <T, V> V cloneFather(T from, V to, Class<V> vClass) {
        try {
            return JSONObject.parseObject(JSONObject.toJSONString(from), vClass);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    public static String upperHeadChar(String in) {
        String head = in.substring(0, 1);
        String out = head.toUpperCase() + in.substring(1, in.length());
        return out;
    }

    public static Map convertBeanToMap(Object bean) {
        try {
            Class type = bean.getClass();
            Map returnMap = new HashMap();
            BeanInfo beanInfo = Introspector.getBeanInfo(type);

            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                if (!propertyName.equals("class")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(bean, new Object[0]);
                    if (result != null) {
                        returnMap.put(propertyName, result);
                    } else {
                        returnMap.put(propertyName, "");
                    }
                }
            }
            return returnMap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getIpAddress() {
        try {
            // node7 服务器会报错
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            log.info("ip is :{}",hostAddress);
            return hostAddress;
        } catch (Exception e) {
            log.error("IP地址获取失败" + e.toString());
        }
        return "";
    }

    public static Boolean hasCastString(String param){
        Boolean result = Boolean.FALSE;
        if(CommonConstant.STRING_STR.equalsIgnoreCase(param) || CommonConstant.DATE_STR.equalsIgnoreCase(param) ){
            result = Boolean.TRUE;
        }
        return result;
    }

}

